package com.hlkj.baojin.service.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.hlkj.baojin.entity.vo.OrganizationTree;
import com.hlkj.baojin.service.IUserService;
import com.hlkj.baojin.utils.ErrororUtil;
import com.hlkj.baojin.utils.hik.LogUtil;
import com.hlkj.baojin.utils.hik.WebServiceConstant;
import com.hlkj.baojin.utils.hik.WebServiceUtil;
import com.hlkj.baojin.utils.hik.XmlUtil;
import com.hlkj.baojin.entity.vo.CameraInfo;
import com.hlkj.baojin.entity.vo.Organization;
import com.hlkj.baojin.service.HKWebService;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author 徐其伟
 * @Description:
 * @date 19-1-3 下午4:43
 */
@Service
public class HKWebServiceImpl implements HKWebService {
    @Autowired
    private IUserService userService;

    private String serviceIp = "122.227.217.10";// 服务器ip
    private int servicePort = 90;

    private String tgt;
    private String userName = "admin";
    private String pacip = "646cb0d858403940505b67101a95f676088e71529352352f96b9f2e497e3d868";

    @Override
    public String login() {
        if(tgt != null){
            return tgt;
        }
        Object[] opArgs = new Object[] { userName, pacip, serviceIp};
        String xmlString = getXml("", WebServiceConstant.VmsSdkWebService_sdkLogin, opArgs);
        try {
            XmlUtil.parseXml(xmlString);
        } catch (Exception e) {
            LogUtil.logError(this, "webservice调用失败");
        }

        try {
            List<Element> list = XmlUtil.getRows();// 判断result_code是不是等于0
            String s = XmlUtil.getStringAttr(list.get(0), "tgt");
            System.out.println(s);
            tgt = s;
            return tgt;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String getToken() {
        try {
            String s = login();
            if (StringUtils.isNotBlank(s)) {
                String xmlString = getXml("", WebServiceConstant.VmsSdkWebService_applyToken, s);
                try {
                    XmlUtil.parseXml(xmlString);
                } catch (Exception e) {
                    LogUtil.logError(this, "webservice调用失败");
                }
                List<Element> list = XmlUtil.getRows();// 判断result_code是不是等于0

                String token = XmlUtil.getStringAttr(list.get(0), "st");
                if(token == null){
                    tgt = null;
                    return getToken();
                }
                return token;
            }
        } catch (Exception e) {
            LogUtil.logError(this, "无法获取令牌信息");
        }
        return null;
    }

    @Override
    public List<Organization> getResource(String resType) {
        try {
            String token = getToken();
            Object[] opArgs = new Object[] { token, resType, 1, 500, "10052",
                    null, 0 };
            String orgXmlString = getXml("",
                    WebServiceConstant.VmsSdkWebService_getResourceByPage, opArgs);
            XmlUtil.parseXml(orgXmlString);
            List<Organization> list = XmlUtil.getVos(Organization.class);
            return list;
        } catch (Exception e) {
            LogUtil.logError(this, "无法获取资源信息");
        } finally {
        }
        return Lists.newArrayList();
    }

    @Override
    public List getOrgAndCameraZTreeByOrgId(String id) {
        List<Organization> resource = getResource("1000");
        return getOrgAndCamera(getOrgById(id, resource), resource, true);
    }
    @Override
    public List getOrgAndCameraZTreeByOrgIndexCode(String indexCode) {
        List<Organization> resource = getResource("1000");
        List<Organization> collect = resource.stream().filter(org -> {
            if (indexCode == null)
                return org.getId() == null;
            return indexCode.equals(org.getIndexCode());
        }).collect(Collectors.toList());
        ErrororUtil.isTrue(collect.size()==0,"获取设备","该公司未绑定监控系统数据，获取设备失败，请联系管理员");
        Organization organization = collect.get(0);
        return getOrgAndCamera(organization, resource, false);
    }

    @Override
    public List getOrgAndCameraZTreeByCamera(String[] indexCode) {
        List result = Lists.newArrayList();
        //根据indexCode数组得到设备详细信息
        List<CameraInfo> cameraList = getCameraByIndexCode(indexCode);
        //所有组织一次性取到内存 减少webservice调用
        List<Organization> resource = getResource("1000");
        //需要看的公司
        Set<Organization> orgSet = Sets.newHashSet();
        //
        cameraList.forEach(camera -> {
            Organization org1 = getOrgById(camera.getOrgId() + "", resource);//王龙1
            if(org1.getParentId() == null){
                orgSet.add(org1);
                return;
            }
            Organization org2 = getOrgById(org1.getParentId(), resource);//王龙公司
            if(org2.getParentId() == null){
                orgSet.add(org2);
                return;
            }
            Organization org3 = getOrgById(org2.getParentId(), resource);//区域
            if(org3.getParentId() == null){
                orgSet.add(org1);
                return;
            }
            orgSet.add(org2);
        });

        orgSet.forEach(org -> {
            result.addAll(getOrgAndCamera(org, resource, true));
        });
        return result;

    }

    private Organization getOrgById(String id, List<Organization> resource) {
        return resource.stream().filter(org -> {
            if (id == null)
                return org.getId() == null;
            return id.equals(org.getId());
        }).collect(Collectors.toList()).get(0);
    }

    /** 查询organization组织下的子组织及摄像头
     * @param organization
     * @param resource 所有组织
     * @return
     */
    private List getOrgAndCamera(Organization organization, List<Organization> resource, boolean addOrg) {
        List result = Lists.newArrayList();
        if(organization == null){
            return result;
        }
        if(addOrg) {
            result.add(organization);
        }
        List<Organization> orgList = resource.stream().filter(org -> {
            if (organization.getId() == null)
                return org.getParentId() == null;
            return organization.getId().equals(org.getParentId());
        }).collect(Collectors.toList());
        //无其他子节点
        if(orgList.size() == 0){
            result.addAll(listCameraByOrgIndexCode(organization.getIndexCode()));
        }else{
            orgList.forEach(org -> {
                result.addAll(getOrgAndCamera(org, resource, addOrg));
            });
        }
        return result;
    }

    @Override
    public List<CameraInfo> listCameraByOrgIndexCode(String indexCode) {
        if (indexCode != null) {
            try {
                String token = getToken();
                Object[] opArgs = new Object[] { token, WebServiceConstant.TYPE_CAMERA,
                        indexCode, "10052" };
                String camXmlString = getXml("",
                        WebServiceConstant.VmsSdkWebService_getResourceByOrgCode, opArgs);
                XmlUtil.parseXml(camXmlString);
                List<CameraInfo> list = XmlUtil.getVos(CameraInfo.class);
                for (CameraInfo cameraInfo : list) {
                    cameraInfo.setId("camera" + cameraInfo.getId());
                }
                return list;
            } catch (Exception e) {
                LogUtil.logError(this, "无法获取监控点信息");
            }
        }
        return null;
    }

    @Override
    public List<CameraInfo> getCameraByIndexCode(String... indexCodes) {
        if (indexCodes != null) {
            try {
                String token = getToken();
                Object[] opArgs = new Object[] { token, WebServiceConstant.TYPE_CAMERA,
                        indexCodes};
                String camXmlString = getXml("",
                        WebServiceConstant.VmsSdkWebService_getResourceByCodes, opArgs);
                XmlUtil.parseXml(camXmlString);
                List<CameraInfo> list = XmlUtil.getVos(CameraInfo.class);
                return list;
            } catch (Exception e) {
                LogUtil.logError(this, "无法获取监控点信息");
            }
        }
        return null;
    }

    @Override
    public String getStream(String indexCode) {
        try {
            String token = getToken();
            Object[] opArgs = new Object[] { token, indexCode, serviceIp };
            String streamXmlString = getXml("",
                    WebServiceConstant.VmsSdkWebService_getPreviewOcxOptions, opArgs);
            streamXmlString = streamXmlString.replace("<StreamType>0</StreamType>","<StreamType>1</StreamType>");
            return streamXmlString;
        } catch (Exception e) {
            LogUtil.logError(this, "无法获取预览信息");
        }
        return null;
    }

    @Override
    public List<OrganizationTree> getOrganizationTree() {
        List<Organization> resource = getResource(WebServiceConstant.TYPE_ORGANIZATION + "");
        List<OrganizationTree> result = Lists.newArrayList();
        result.addAll(getChildren(null, resource));
        return result;
    }

    /**
     * 输入 token, indexCode, resType, operCode（操作码）参数
     * 调用checkResourcePrivilege接口获取相应操作权限
     *
     * @author limingyi
     */
    @Override
    public String checkResourcePrivilege(String indexCode, int operCode) {
        try {
            String token = getToken();
            Object[] opArgs = new Object[] { token, indexCode, "10000",
                    operCode };
            String rscXmlString = getXml("",
                    WebServiceConstant.VmsSdkWebService_checkResourcePrivilege, opArgs);
            return rscXmlString;
        } catch (Exception e) {
            LogUtil.logError(this, "无法获取资源信息");
        }
        return null;
    }

    @Override
    public String getPlaybackInfo(String indexCode, String beginTime, String endTime, String storeType) {
        try {
            String token = getToken();
            // 输入的参数集合

            Object[] opArgs = new Object[] { token, indexCode, serviceIp,
                    beginTime, endTime, storeType };
            // 调用回放接口获取返回xml信息
            String streamXmlString = getXml("",
                    WebServiceConstant.VmsSdkWebService_getPlaybackOcxOptions, opArgs);
            return streamXmlString;
        } catch (Exception e) {
            LogUtil.logError(this, "无法获取回放信息");
        }
        return null;
    }

    private List<OrganizationTree> getChildren(String indexCode, List<Organization> resource) {
        List<OrganizationTree> result = Lists.newArrayList();
        List<Organization> collect = resource.stream().filter(org -> {
            if (indexCode == null)
                return org.getParentId() == null;
            return indexCode.equals(org.getParentId());
        }).collect(Collectors.toList());
        collect.forEach(org -> {
            OrganizationTree organizationTree = new OrganizationTree();
            organizationTree.setLabel(org.getOrgName());
            organizationTree.setValue(org.getIndexCode());
            organizationTree.setChildren(getChildren(org.getId(), resource));
            result.add(organizationTree);
        });
        return result;
    }

    public String getXml(String prefix, String method, Object... params) {
        try {
            WebServiceUtil service = new WebServiceUtil();
            String Xml = service.getCommonXml(serviceIp, servicePort,
                    prefix, String.class, method, params);
            return Xml;
        } catch (Exception e) {
            LogUtil.logError(this, "无法获取信息");
        }
        return null;
    }
}
